<template>
	<div class="logic-flow-view">
		<!-- 辅助工具栏 -->
		<Control class="demo-control" v-if="lf" :lf="lf" @catData="$_catData" @saveModel="$_saveModel"></Control>
		<!-- 节点面板 -->
		<NodePanel v-if="lf" :lf="lf" :nodeList="nodeList"></NodePanel>
		<!-- 画布 -->
		<div id="LF-view" ref="container"></div>
		<!-- 用户节点自定义操作面板 -->
		<AddPanel v-if="showAddPanel" class="add-panel" :style="addPanelStyle" :lf="lf" :nodeData="addClickNode" @addNodeFinish="hideAddPanel">
		</AddPanel>
		<!-- 属性面板 -->
		<el-drawer title="设置节点属性" v-model="dialogVisible" direction="rtl" size="700px" :before-close="closeDialog">
			<PropertyDialog v-if="dialogVisible" :nodeData="clickNode" :lf="lf" @setPropertiesFinish="closeDialog"></PropertyDialog>
		</el-drawer>
		<!-- 数据查看面板 -->
		<el-dialog title="数据" v-model="dataVisible" width="50%">
			<DataDialog :graphData="graphData"></DataDialog>
		</el-dialog>
	</div>
</template>
<script lang="ts">
import LogicFlow from '@logicflow/core';
import { Menu, Snapshot, MiniMap } from '@logicflow/extension';
import '@logicflow/core/dist/style/index.css';
import '@logicflow/extension/lib/style/index.css';
import NodePanel from '/@/components/LF/NodePanel.vue';
import AddPanel from '/@/components/LF/AddPanel.vue';
import Control from '/@/components/LF/Control.vue';
import PropertyDialog from '/@/components/LF/propertySetting/PropertyDialog.vue';
import DataDialog from '/@/components/LF/DataDialog.vue';
import { nodeList } from '/@/components/LF/config';
import { useRoute } from 'vue-router';
import {demoData} from '/@/components/LF/data.ts'
import {
	registerStart,
	registerUser,
	registerEnd,
	registerPush,
	registerCondition,
	registerPolyline,
	registerTask,
	registerConnect,
} from '/@/components/LF/registerNode';
import {ElMessage} from "element-plus";
import {getNodeData, saveModeNode} from "/@/api/flow/flowModel";
export default {
	name: 'apiV1FlowFlowModelDesign',
	components: { NodePanel, AddPanel, Control, PropertyDialog, DataDialog },
	data() {
		return {
      route : useRoute(),
      modelId:0,
			lf: null,
			showAddPanel: false,
			addPanelStyle: {
				top: 0,
				left: 0,
			},
			nodeData: null,
			addClickNode: null,
			clickNode: null,
			dialogVisible: false,
			graphData: null,
			dataVisible: false,
			config: {
				background: {
					backgroundColor: '#f7f9ff',
				},
				grid: {
					size: 10,
					visible: false,
				},
				keyboard: {
					enabled: true,
				},
				edgeTextDraggable: true,
				hoverOutline: false,
			},
			moveData: {},
			nodeList,
		};
	},
	mounted() {
    if (this.route.query.id){
      this.modelId = parseInt(this.route.query.id as string)
    }else{
      ElMessage.error('参数错误');
      return
    }
		this.$_initLf();
	},
	methods: {
		$_initLf() {
			// 画布配置
			const lf = new LogicFlow({
				...this.config,
				plugins: [Menu, MiniMap, Snapshot],
				container: this.$refs.container,
			});
			this.lf = lf;
			// 设置主题
			lf.setTheme({
				circle: {
					stroke: '#000000',
					strokeWidth: 1,
					outlineColor: '#88f',
				},
				rect: {
					outlineColor: '#88f',
					strokeWidth: 1,
				},
				polygon: {
					strokeWidth: 1,
				},
				polyline: {
					stroke: '#000000',
					hoverStroke: '#000000',
					selectedStroke: '#000000',
					outlineColor: '#88f',
					strokeWidth: 1,
				},
				nodeText: {
					color: '#000000',
				},
				edgeText: {
					color: '#000000',
					background: {
						fill: '#f7f9ff',
					},
				},
			});
			this.$_registerNode();
		},
		// 自定义
		$_registerNode() {
			registerStart(this.lf);
			registerUser(this.lf);
			registerEnd(this.lf);
			registerPush(this.lf, this.clickPlus, this.mouseDownPlus);
			registerCondition(this.lf);
			registerPolyline(this.lf);
			registerTask(this.lf);
			registerConnect(this.lf);
			this.$_render();
		},
		$_render() {
      //获取节点数据
      getNodeData(this.modelId).then((res:any)=>{
        const nodes = (res.data.nodes??[]).map((item:any)=>{
          const node = {
            id: item.nodeId,
            type: item.nodeType,
            x: item.nodePosition.x,
            y: item.nodePosition.y,
            text: item.nodeText??{},
            properties: {
              text: item.nodeText?.value,
              actionRule: item.nodeActionRule,
              approveRule: item.nodeRule,
              notice: item.notice ?? [],
              rollback: item.rollback
            }
          }
          this.setReceiver(node,item.nodeReceiver)
          return node
        })
        const edges = (res.data.edges??[]).map((item:any)=>{
            return {
              id: item.id,
              type: item.lineType,
              sourceNodeId: item.sourceNodeId,
              targetNodeId: item.targetNodeId,
              startPoint:item.startPoint,
              endPoint:item.endPoint,
              properties: item.properties,
              pointsList: item.pointsList,
              text:item.text
            }
        })
        this.lf.render({nodes,edges});
        //this.lf.render(demoData);
        this.$_LfEvent();
      })
		},
    setReceiver(node:any,receivers:Array<string>){
      switch(node.properties.actionRule){
        case 1://角色
          node.properties.roleIds = receivers
          break
        case 2://部门
        case 3://部门负责人
          node.properties.deptIds = receivers
          break
        case 4://指定人员
          node.properties.userIds = receivers
          break
        case 5://岗位
          node.properties.postIds = receivers
      }
    },
		$_getData() {
			const data = this.lf.getGraphData();
			console.log(JSON.stringify(data));
		},
		$_LfEvent() {
			this.lf.on('node:click', ({ data }) => {
				console.log('node:click', data);
				this.$data.clickNode = data;
				this.$data.dialogVisible = true;
			});
			this.lf.on('edge:click', ({ data }) => {
				console.log('edge:click', data);
				//this.$data.clickNode = data;
				//this.$data.dialogVisible = true;
			});
			this.lf.on('element:click', () => {
				this.hideAddPanel();
			});
			this.lf.on('edge:add', ({ data }) => {
				console.log('edge:add', data);
			});
			this.lf.on('node:mousemove', ({ data }) => {
				console.log('node:mousemove');
				this.moveData = data;
			});
			this.lf.on('blank:click', () => {
				this.hideAddPanel();
			});
			this.lf.on('connection:not-allowed', (data) => {
        console.log('connection:not-allowed',data)
			});
			this.lf.on('node:mousemove', () => {
				console.log('on mousemove');
			});
		},
		clickPlus(e, attributes) {
			e.stopPropagation();
			console.log('clickPlus', e, attributes);
			const { clientX, clientY } = e;
			console.log(clientX, clientY);
			this.$data.addPanelStyle.top = clientY - 40 + 'px';
			this.$data.addPanelStyle.left = clientX + 'px';
			this.$data.showAddPanel = true;
			this.$data.addClickNode = attributes;
		},
		mouseDownPlus(e, attributes) {
			e.stopPropagation();
			console.log('mouseDownPlus', e, attributes);
		},
		hideAddPanel() {
			this.$data.showAddPanel = false;
			this.$data.addPanelStyle.top = 0;
			this.$data.addPanelStyle.left = 0;
			this.$data.addClickNode = null;
		},
		closeDialog() {
			this.$data.dialogVisible = false;
		},
		$_catData() {
			this.$data.graphData = this.$data.lf.getGraphData();
			this.$data.dataVisible = true;
		},
    $_saveModel(){
      const _this = this
      const data = _this.$data.lf.getGraphData()
      const nodes = data.nodes.map((item:any)=>{
        return {
          nodeId:item.id,
          modelId:_this.modelId,
          nodeType:item.type,
          nodePosition:{x:item.x,y:item.y},
          nodeText:item.text,
          nodeActionRule:item.properties?.actionRule,
          nodeReceiver: _this.getNodeReceiver(item.properties?.actionRule,item),
          nodeRule:item.properties?.approveRule,
          notice:item.properties?.notice,
          rollback:item.properties?.rollback,
        }
      })
      const edges = data.edges.map((item:any)=>{
        return {
          modelId:_this.modelId,
          lineType:item.type,
          sourceNodeId:item.sourceNodeId,
          targetNodeId:item.targetNodeId,
          startPoint:item.startPoint,
          endPoint:item.endPoint,
          properties:item.properties,
          text:item.text,
          pointsList:item.pointsList
        }
      })
      const postData = {
        modelId:_this.modelId,
        nodes:nodes,
        edges:edges
      }
      saveModeNode(postData).then((res:any)=>{
        if(res.code===0){
          ElMessage.success('保存成功');
        }else{
          ElMessage.error(res.data.message);
        }
      })
    },
    getNodeReceiver(rule:number,item:any){
      switch(rule){
        case 1://角色
        return item.properties.roleIds
        case 2://部门
        case 3://部门负责人
        return item.properties.deptIds
        case 4://指定人员
        return item.properties.userIds
        case 5://岗位
        return item.properties.postIds
      }
      return []
    }
	},
};
</script>
<style scoped lang="scss">
.logic-flow-view {
  height: 100vh;
  position: relative;
}
.demo-title{
  text-align: center;
  margin: 20px;
}
.demo-control{
  position: absolute;
  top: 10px;
  left: 50px;
  z-index: 2;
}
#LF-view{
  height: 100%;
  outline: none;
}
.time-plus{
  cursor: pointer;
}
.add-panel {
  position: absolute;
  z-index: 11;
  background-color: white;
  padding: 10px 5px;
}
.el-drawer__body {
  height: 80%;
  overflow: auto;
  margin-top: -30px;
  z-index: 3;
}

@keyframes lf_animate_dash {
  to {
    stroke-dashoffset: 0;
  }
}
</style>
